<template>
  <div class="cloze">
    <el-form-item :label="data.label" :label-width="data.label ? data.labelWidth : '1px'" style="margin-bottom: 0px">
      <template v-for="(element, index) in elements">
        <br :key="index" v-if="element.type === 'br'" />
        <template v-else-if="element.type === 'text'">{{ element.value }}</template>
        <div :key="index" v-else class="inline-item" :style="element.style">
          <el-form-item style="margin-bottom: 0px" v-if="element.type === 'input'" label-width="1px" :prop="element.prop" :rules="element.rules">
            <el-input clearable size="small" :value="form[element.prop]" @input="handleInput(element, $event)" :disabled="element.disabled" />
          </el-form-item>
          <el-form-item style="margin-bottom: 0px" v-if="element.type === 'radio-group'" label-width="1px" :prop="element.prop">
            <el-radio-group :value="form[element.prop]" @input="handleInput(element, $event)" :style="element.style">
              <el-radio v-for="option in element.options" :key="option.value" :label="option.value" :disabled="element.disabled">{{option.label}}</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item style="margin-bottom: 0px" v-if="element.type === 'checkbox-group' && form[element.prop]" label-width="1px" :prop="element.prop">
            <el-checkbox-group :value="form[element.prop]" @input="handleInput(element, $event)">
              <el-checkbox v-for="option in element.options" :key="option.value" :label="option.value" :disabled="element.disabled">{{option.label}}</el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </div>
      </template>
    </el-form-item>
  </div>
</template>

<script>
import nzhcn from "nzh/cn";

export default {
  name: "cloze-field",
  props: {
    form: {
      type: Object,
      required: true,
    },
    data: {
      type: Object,
      required: true,
    },
  },
  computed: {
    elements: function () {
      let nextElements = [this.data.tpl];
      for (let i = 0; i < this.data.fields.length; i++) {
        const field = this.data.fields[i];

        let _elements = [];
        for (let m = 0; m < nextElements.length; m++) {
          const element = nextElements[m];
          const parsedElements = this.parser(field, element);
          _elements = _elements.concat(parsedElements);
        }
        nextElements = _elements;
      }

      let _elements = [];
      for (let i = 0; i < nextElements.length; i++) {
        const nextElement = nextElements[i];

        if (typeof nextElement === "string") {
          const parts = nextElement.split("<br />");
          if (parts.length === 1) {
            _elements = _elements.concat(parts);
          } else {
            const _parts = [];
            for (let n = 0; n < parts.length; n++) {
              const part = parts[n];

              if (part) {
                _parts.push(part);
              }
              if (n+1 !== parts.length) {
                _parts.push({ type: "br" });
              }
            }
            _elements = _elements.concat(_parts);
          }
        } else {
          _elements.push(nextElement)
        }
      }
      nextElements = _elements;

      for (let i = 0; i < nextElements.length; i++) {
        const element = nextElements[i];

        if (typeof element === "string") {
          nextElements[i] = { type: "text", value: element };
        } else if (element.isDisabled) {
          const isDisabled = element.isDisabled;
          let separator;
          let reverse;
          if (isDisabled.includes("!=")) {
            reverse = true;
            separator = "!=";
          } else if (isDisabled.includes("=")) {
            reverse = false;
            separator = "=";
          }
          const [key, value] = isDisabled.split(separator);
          let matching;
          if (value.includes("[")) {
            const _values = value.substring(1, value.length-1).split(",");
            const selecteds = [...this.form[key]];
            matching = _values.every(v => selecteds.includes(v));
          } else {
            matching = this.form[key] === value;
          }
          nextElements[i].disabled = reverse ? !matching : matching;
        }
      }

      return nextElements;
    },
  },
  methods: {
    handleInput(element, e) {
      const { prop, syncTo } = element;
      this.$emit("value-change", prop, e);
      if (syncTo) {
        const [toProp, filter] = syncTo.split("|")
        let toValue = "";
        switch (filter) {
          case "FinancialNumerals":
            toValue = nzhcn.encodeB(e);
            break;
          default:
            toValue = e;
            break;
        }
        this.$emit("value-change", toProp, toValue);
      }
    },
    parser(field, element) {
      if (typeof element !== "string") {
        return [element];
      }

      const items = element.split(field.key);

      if (items.length === 1) {
        return [element];
      }

      const elements = [];
      if (items[0]) {
        elements.push(items[0]);
      }
      elements.push(field);
      if (items[1]) {
        elements.push(items[1]);
      }
      return elements;
    },
  },
};
</script>

<style>
.cloze {
  display: inline-block;
}
.inline-item {
  display: inline-block;
  margin: 0 8px 0;
}
</style>
